public Task <IInlineRenameLocationSet> FindRenameLocationsAsync(OptionSet optionSet, CancellationToken cancellationToken) { Task <RenameLocationSet> renameTask; lock (_gate) { if (_underlyingFindRenameLocationsTask == null) { // If this is the first call, then just start finding the initial set of rename // locations. _underlyingFindRenameLocationsTask = RenameLocationSet.FindAsync( this.RenameSymbol, _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, ISymbol renameSymbol, CancellationToken cancellationToken) { this.CanRename = true; _refactorNotifyServices = refactorNotifyServices; _document = document; this.RenameSymbol = renameSymbol; this.HasOverloads = RenameLocationSet.GetOverloadedSymbols(this.RenameSymbol).Any(); _isRenamingAttributePrefix = CanRenameAttributePrefix(document, triggerSpan, cancellationToken); this.TriggerSpan = GetReferenceEditSpan(new InlineRenameLocation(document, triggerSpan), cancellationToken); _shortenedTriggerSpan = this.TriggerSpan != triggerSpan; }
/// <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="cancellationToken">The cancellation token.</param> /// <returns>A conflict resolution containing the new solution.</returns> public static Task<ConflictResolution> ResolveConflictsAsync( RenameLocationSet renameLocationSet, string originalText, string replacementText, OptionSet optionSet, 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, cancellationToken); return session.ResolveConflictsAsync(); }
public Session(RenameLocationSet renameLocationSet, Location renameSymbolDeclarationLocation, string originalText, string replacementText, OptionSet optionSet, CancellationToken cancellationToken) { _renameLocationSet = renameLocationSet; _renameSymbolDeclarationLocation = renameSymbolDeclarationLocation; _originalText = originalText; _replacementText = replacementText; _optionSet = optionSet; _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 Session(RenameLocationSet renameLocationSet, Location renameSymbolDeclarationLocation, string originalText, string replacementText, OptionSet optionSet, CancellationToken cancellationToken) { _renameLocationSet = renameLocationSet; _renameSymbolDeclarationLocation = renameSymbolDeclarationLocation; _originalText = originalText; _replacementText = replacementText; _optionSet = optionSet; _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); }
/// <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="cancellationToken">The cancellation token.</param> /// <returns>A conflict resolution containing the new solution.</returns> public static Task <ConflictResolution> ResolveConflictsAsync( RenameLocationSet renameLocationSet, string originalText, string replacementText, OptionSet optionSet, 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, cancellationToken); return(session.ResolveConflictsAsync()); }
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().ReplaceNode(fieldDeclaration.GetSyntax(), fieldDeclaration.GetSyntax().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).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).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())); }
public InlineRenameLocationSet(SymbolInlineRenameInfo renameInfo, RenameLocationSet renameLocationSet) { _renameInfo = renameInfo; _renameLocationSet = renameLocationSet; this.Locations = renameLocationSet.Locations.Where(l => !l.IsCandidateLocation).Select(ConvertLocation).ToList(); }