Example #1
0
        public static async Task <Solution> RenameSymbolAsync(Solution solution, ISymbol symbol, string newName, OptionSet optionSet, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (solution == null)
            {
                throw new ArgumentNullException(nameof(solution));
            }

            if (symbol == null)
            {
                throw new ArgumentNullException(nameof(symbol));
            }

            if (string.IsNullOrEmpty(newName))
            {
                throw new ArgumentException("newName");
            }

            cancellationToken.ThrowIfCancellationRequested();

            optionSet = optionSet ?? solution.Workspace.Options;
            var renameLocationSet = await RenameLocationSet.FindAsync(symbol, solution, optionSet, cancellationToken).ConfigureAwait(false);

            var conflictResolution = await ConflictEngine.ConflictResolver.ResolveConflictsAsync(renameLocationSet, symbol.Name, newName, optionSet, cancellationToken).ConfigureAwait(false);

            return(conflictResolution.NewSolution);
        }
Example #2
0
        /// <summary>
        /// Find the locations that need to be renamed.
        /// </summary>
        public static async Task <RenameLocationSet> FindAsync(ISymbol symbol, Solution solution, OptionSet optionSet, CancellationToken cancellationToken)
        {
            Contract.ThrowIfNull(symbol);
            using (Logger.LogBlock(FunctionId.Rename_AllRenameLocations, cancellationToken))
            {
                symbol = await ReferenceProcessing.FindDefinitionSymbolAsync(symbol, solution, cancellationToken).ConfigureAwait(false);

                var originalSymbolResult = await AddLocationsReferenceSymbolsAsync(symbol, solution, cancellationToken).ConfigureAwait(false);

                var intermediateResult = new RenameLocationSet(symbol, solution, optionSet, originalSymbolResult, overloadsResult: null, stringsResult: null, commentsResult: null);

                return(await intermediateResult.FindWithUpdatedOptionsAsync(optionSet, cancellationToken).ConfigureAwait(false));
            }
        }
 public InlineRenameLocationSet(SymbolInlineRenameInfo renameInfo, RenameLocationSet renameLocationSet)
 {
     _renameInfo = renameInfo;
     _renameLocationSet = renameLocationSet;
     this.Locations = renameLocationSet.Locations.Where(l => !l.IsCandidateLocation || l.IsMethodGroupReference).Select(ConvertLocation).ToList();
 }
Example #4
0
        /// <summary>
        /// Find the locations that need to be renamed.
        /// </summary>
        public static async Task<RenameLocationSet> FindAsync(ISymbol symbol, Solution solution, OptionSet optionSet, CancellationToken cancellationToken)
        {
            Contract.ThrowIfNull(symbol);
            using (Logger.LogBlock(FunctionId.Rename_AllRenameLocations, cancellationToken))
            {
                symbol = await ReferenceProcessing.FindDefinitionSymbolAsync(symbol, solution, cancellationToken).ConfigureAwait(false);
                var originalSymbolResult = await AddLocationsReferenceSymbolsAsync(symbol, solution, cancellationToken).ConfigureAwait(false);
                var intermediateResult = new RenameLocationSet(symbol, solution, optionSet, originalSymbolResult, overloadsResult: null, stringsResult: null, commentsResult: null);

                return await intermediateResult.FindWithUpdatedOptionsAsync(optionSet, cancellationToken).ConfigureAwait(false);
            }
        }
        private async Task<Result> EncapsulateFieldAsync(IFieldSymbol field, Document document, bool updateReferences, CancellationToken cancellationToken)
        {
            var originalField = field;
            var finalNames = GeneratePropertyAndFieldNames(field);
            var finalFieldName = finalNames.Item1;
            var generatedPropertyName = finalNames.Item2;

            // Annotate the field declarations so we can find it after rename.
            var fieldDeclaration = field.DeclaringSyntaxReferences.First();
            var declarationAnnotation = new SyntaxAnnotation();
            document = document.WithSyntaxRoot(fieldDeclaration.SyntaxTree.GetRoot(cancellationToken).ReplaceNode(fieldDeclaration.GetSyntax(cancellationToken),
                fieldDeclaration.GetSyntax(cancellationToken).WithAdditionalAnnotations(declarationAnnotation)));

            var solution = document.Project.Solution;

            foreach (var linkedDocumentId in document.GetLinkedDocumentIds())
            {
                var linkedDocument = solution.GetDocument(linkedDocumentId);
                var linkedRoot = await linkedDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
                var linkedFieldNode = linkedRoot.FindNode(fieldDeclaration.Span);
                if (linkedFieldNode.Span != fieldDeclaration.Span)
                {
                    continue;
                }

                var updatedRoot = linkedRoot.ReplaceNode(linkedFieldNode, linkedFieldNode.WithAdditionalAnnotations(declarationAnnotation));
                solution = solution.WithDocumentSyntaxRoot(linkedDocumentId, updatedRoot);
            }

            document = solution.GetDocument(document.Id);

            // Resolve the annotated symbol and prepare for rename.

            var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            var compilation = semanticModel.Compilation;
            field = field.GetSymbolKey().Resolve(compilation, cancellationToken: cancellationToken).Symbol as IFieldSymbol;
            Solution solutionNeedingProperty = null;

            // We couldn't resolve field after annotating its declaration. Bail
            if (field == null)
            {
                return null;
            }

            if (updateReferences)
            {
                var locationsToIgnore = SpecializedCollections.EmptySet<TextSpan>();
                var optionSet = document.Project.Solution.Workspace.Options;

                if (field.IsReadOnly)
                {
                    var locationSet = await RenameLocationSet.FindAsync(field, document.Project.Solution, optionSet, cancellationToken).ConfigureAwait(false);
                    var constructorSyntaxes = GetConstructorNodes(field.ContainingType);
                    var locations = locationSet.Locations.Where(l => constructorSyntaxes.Any(c => c.Span.IntersectsWith(l.Location.SourceSpan)));

                    if (locations.Any())
                    {
                        locationsToIgnore = locations.Select(l => l.Location.SourceSpan).ToSet();
                        locationSet = new RenameLocationSet(locations.ToSet(), field, document.Project.Solution, locationSet.ReferencedSymbols, locationSet.ImplicitLocations);

                        var resolution = await ConflictResolver.ResolveConflictsAsync(locationSet, field.Name, finalFieldName, optionSet, cancellationToken).ConfigureAwait(false);
                        document = resolution.NewSolution.GetDocument(document.Id);

                        semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
                        compilation = semanticModel.Compilation;
                        field = field.GetSymbolKey().Resolve(compilation, cancellationToken: cancellationToken).Symbol as IFieldSymbol;
                    }
                }

                var renameLocationSet = await RenameLocationSet.FindAsync(field, document.Project.Solution, optionSet, cancellationToken).ConfigureAwait(false);
                renameLocationSet = new RenameLocationSet(renameLocationSet.Locations.Where(l => !locationsToIgnore.Contains(l.Location.SourceSpan)).ToSet(),
                    renameLocationSet.Symbol, renameLocationSet.Solution, renameLocationSet.ReferencedSymbols, renameLocationSet.ImplicitLocations);

                if (renameLocationSet.Locations.Any() || renameLocationSet.ImplicitLocations.Any())
                {
                    var conflictResolution = await ConflictResolver.ResolveConflictsAsync(renameLocationSet, field.Name, generatedPropertyName, optionSet, cancellationToken).ConfigureAwait(false);

                    if (!conflictResolution.ReplacementTextValid)
                    {
                        return null;
                    }

                    solutionNeedingProperty = conflictResolution.NewSolution;
                    document = solutionNeedingProperty.GetDocument(document.Id);
                }
            }
            else
            {
                solutionNeedingProperty = document.Project.Solution;
                document = solutionNeedingProperty.GetDocument(document.Id);
            }

            var markFieldPrivate = field.DeclaredAccessibility != Accessibility.Private;
            var rewrittenFieldDeclaration = await RewriteFieldNameAndAccessibility(finalFieldName, markFieldPrivate, document, declarationAnnotation, cancellationToken).ConfigureAwait(false);

            document = await Formatter.FormatAsync(document.WithSyntaxRoot(rewrittenFieldDeclaration), Formatter.Annotation, cancellationToken: cancellationToken).ConfigureAwait(false);

            solution = document.Project.Solution;
            foreach (var linkedDocumentId in document.GetLinkedDocumentIds())
            {
                var linkedDocument = solution.GetDocument(linkedDocumentId);
                var updatedLinkedRoot = await RewriteFieldNameAndAccessibility(finalFieldName, markFieldPrivate, linkedDocument, declarationAnnotation, cancellationToken).ConfigureAwait(false);
                var updatedLinkedDocument = await Formatter.FormatAsync(linkedDocument.WithSyntaxRoot(updatedLinkedRoot), Formatter.Annotation, cancellationToken: cancellationToken).ConfigureAwait(false);
                solution = updatedLinkedDocument.Project.Solution;
            }

            document = solution.GetDocument(document.Id);

            semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            compilation = semanticModel.Compilation;

            var newRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
            var newDeclaration = newRoot.GetAnnotatedNodes<SyntaxNode>(declarationAnnotation).First();
            field = semanticModel.GetDeclaredSymbol(newDeclaration, cancellationToken) as IFieldSymbol;

            var generatedProperty = GenerateProperty(generatedPropertyName, finalFieldName, originalField.DeclaredAccessibility, originalField, field.ContainingType, new SyntaxAnnotation(), document, cancellationToken);

            var codeGenerationService = document.GetLanguageService<ICodeGenerationService>();
            var solutionWithProperty = await AddPropertyAsync(document, document.Project.Solution, field, generatedProperty, cancellationToken).ConfigureAwait(false);

            return new Result(solutionWithProperty, originalField.ToDisplayString(), originalField.GetGlyph());
        }