/// <summary> /// Enables editing the definition of one of the symbol's declarations. /// Partial types and methods may have more than one declaration. /// </summary> /// <param name="symbol">The symbol to edit.</param> /// <param name="editAction">The action that makes edits to the declaration.</param> /// <param name="cancellationToken">An optional <see cref="CancellationToken"/>.</param> /// <returns>The new symbol including the changes.</returns> public async Task <ISymbol> EditOneDeclarationAsync( ISymbol symbol, AsyncDeclarationEditAction editAction, CancellationToken cancellationToken = default) { var currentSymbol = await this.GetCurrentSymbolAsync(symbol, cancellationToken).ConfigureAwait(false); CheckSymbolArgument(currentSymbol, symbol); if (TryGetBestDeclarationForSingleEdit(currentSymbol, out var declaration)) { return(await this.EditDeclarationAsync(currentSymbol, declaration, editAction, cancellationToken).ConfigureAwait(false)); } return(null); }
public async Task <ISymbol> EditOneDeclarationAsync( ISymbol symbol, ISymbol member, AsyncDeclarationEditAction editAction, CancellationToken cancellationToken = default ) { var currentSymbol = await this.GetCurrentSymbolAsync(symbol, cancellationToken) .ConfigureAwait(false); CheckSymbolArgument(currentSymbol, symbol); var currentMember = await this.GetCurrentSymbolAsync(member, cancellationToken) .ConfigureAwait(false); CheckSymbolArgument(currentMember, member); // get first symbol declaration that encompasses at least one of the member declarations var memberDecls = this.GetDeclarations(currentMember).ToList(); var declaration = this.GetDeclarations(currentSymbol) .FirstOrDefault( d => memberDecls.Any( md => md.SyntaxTree == d.SyntaxTree && d.FullSpan.IntersectsWith(md.FullSpan) ) ); if (declaration == null) { throw new ArgumentException( string.Format( WorkspacesResources.The_member_0_is_not_declared_within_the_declaration_of_the_symbol, member.Name ) ); } return(await this.EditDeclarationAsync( currentSymbol, declaration, editAction, cancellationToken ) .ConfigureAwait(false)); }
public Task <ISymbol> EditOneDeclarationAsync( ISymbol symbol, Location location, AsyncDeclarationEditAction editAction, CancellationToken cancellationToken = default) { var sourceTree = location.SourceTree; var doc = _currentSolution.GetDocument(sourceTree) ?? _originalSolution.GetDocument(sourceTree); if (doc != null) { return(EditOneDeclarationAsync(symbol, doc.Id, location.SourceSpan.Start, editAction, cancellationToken)); } throw new ArgumentException("The location specified is not part of the solution.", nameof(location)); }
private async Task <ISymbol> EditOneDeclarationAsync( ISymbol symbol, DocumentId documentId, int position, AsyncDeclarationEditAction editAction, CancellationToken cancellationToken = default ) { var currentSymbol = await this.GetCurrentSymbolAsync(symbol, cancellationToken) .ConfigureAwait(false); CheckSymbolArgument(currentSymbol, symbol); var decl = this.GetDeclarations(currentSymbol) .FirstOrDefault( d => { var doc = _currentSolution.GetDocument(d.SyntaxTree); return(doc != null && doc.Id == documentId && d.FullSpan.IntersectsWith(position)); } ); if (decl == null) { throw new ArgumentNullException( WorkspacesResources.The_position_is_not_within_the_symbol_s_declaration, nameof(position) ); } return(await this.EditDeclarationAsync( currentSymbol, decl, editAction, cancellationToken ) .ConfigureAwait(false)); }
private async Task <ISymbol> EditDeclarationAsync( ISymbol currentSymbol, SyntaxNode declaration, AsyncDeclarationEditAction editAction, CancellationToken cancellationToken ) { var doc = _currentSolution.GetDocument(declaration.SyntaxTree); var editor = await DocumentEditor .CreateAsync(doc, cancellationToken) .ConfigureAwait(false); editor.TrackNode(declaration); await editAction(editor, declaration, cancellationToken).ConfigureAwait(false); var newDoc = editor.GetChangedDocument(); _currentSolution = newDoc.Project.Solution; // try to find new symbol by looking up via original declaration var model = await newDoc.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); var newDeclaration = model.SyntaxTree .GetRoot(cancellationToken) .GetCurrentNode(declaration); if (newDeclaration != null) { var newSymbol = model.GetDeclaredSymbol(newDeclaration, cancellationToken); if (newSymbol != null) { return(newSymbol); } } // otherwise fallback to rebinding with original symbol return(await this.GetCurrentSymbolAsync(currentSymbol, cancellationToken) .ConfigureAwait(false)); }
/// <summary> /// Enables editing all the symbol's declarations. /// Partial types and methods may have more than one declaration. /// </summary> /// <param name="symbol">The symbol to be edited.</param> /// <param name="editAction">The action that makes edits to the declaration.</param> /// <param name="cancellationToken">An optional <see cref="CancellationToken"/>.</param> /// <returns>The new symbol including the changes.</returns> public async Task<ISymbol> EditAllDeclarationsAsync( ISymbol symbol, AsyncDeclarationEditAction editAction, CancellationToken cancellationToken = default(CancellationToken)) { var currentSymbol = await this.GetCurrentSymbolAsync(symbol, cancellationToken).ConfigureAwait(false); CheckSymbolArgument(currentSymbol, symbol); var declsByDocId = this.GetDeclarations(currentSymbol).ToLookup(d => _currentSolution.GetDocument(d.SyntaxTree).Id); var solutionEditor = new SolutionEditor(_currentSolution); foreach (var declGroup in declsByDocId) { var docId = declGroup.Key; var editor = await solutionEditor.GetDocumentEditorAsync(docId, cancellationToken).ConfigureAwait(false); foreach (var decl in declGroup) { editor.TrackNode(decl); // ensure the declaration gets tracked await editAction(editor, decl, cancellationToken).ConfigureAwait(false); } } _currentSolution = solutionEditor.GetChangedSolution(); // try to find new symbol by looking up via original declarations foreach (var declGroup in declsByDocId) { var doc = _currentSolution.GetDocument(declGroup.Key); var model = await doc.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); foreach (var decl in declGroup) { var newDeclaration = model.SyntaxTree.GetRoot(cancellationToken).GetCurrentNode(decl); if (newDeclaration != null) { var newSymbol = model.GetDeclaredSymbol(newDeclaration); if (newSymbol != null) { return newSymbol; } } } } // otherwise fallback to rebinding with original symbol return await GetCurrentSymbolAsync(symbol, cancellationToken).ConfigureAwait(false); }
/// <summary> /// Enables editing the symbol's declaration where the member is also declared. /// Partial types and methods may have more than one declaration. /// </summary> /// <param name="symbol">The symbol to edit.</param> /// <param name="member">A symbol whose declaration is contained within one of the primary symbol's declarations.</param> /// <param name="editAction">The action that makes edits to the declaration.</param> /// <param name="cancellationToken">An optional <see cref="CancellationToken"/>.</param> /// <returns>The new symbol including the changes.</returns> public async Task<ISymbol> EditOneDeclarationAsync( ISymbol symbol, ISymbol member, AsyncDeclarationEditAction editAction, CancellationToken cancellationToken = default(CancellationToken)) { var currentSymbol = await this.GetCurrentSymbolAsync(symbol, cancellationToken).ConfigureAwait(false); CheckSymbolArgument(currentSymbol, symbol); var currentMember = await this.GetCurrentSymbolAsync(member, cancellationToken).ConfigureAwait(false); CheckSymbolArgument(currentMember, member); // get first symbol declaration that encompasses at least one of the member declarations var memberDecls = this.GetDeclarations(currentMember).ToList(); var declaration = this.GetDeclarations(currentSymbol).FirstOrDefault(d => memberDecls.Any(md => md.SyntaxTree == d.SyntaxTree && d.FullSpan.IntersectsWith(md.FullSpan))); if (declaration == null) { throw new ArgumentException(string.Format(WorkspacesResources.The_member_0_is_not_declared_within_the_declaration_of_the_symbol, member.Name)); } return await this.EditDeclarationAsync(currentSymbol, declaration, editAction, cancellationToken).ConfigureAwait(false); }
private async Task<ISymbol> EditOneDeclarationAsync( ISymbol symbol, DocumentId documentId, int position, AsyncDeclarationEditAction editAction, CancellationToken cancellationToken = default(CancellationToken)) { var currentSymbol = await this.GetCurrentSymbolAsync(symbol, cancellationToken).ConfigureAwait(false); CheckSymbolArgument(currentSymbol, symbol); var decl = this.GetDeclarations(currentSymbol).FirstOrDefault(d => { var doc = _currentSolution.GetDocument(d.SyntaxTree); return doc != null && doc.Id == documentId && d.FullSpan.IntersectsWith(position); }); if (decl == null) { throw new ArgumentNullException(WorkspacesResources.The_position_is_not_within_the_symbol_s_declaration, nameof(position)); } return await this.EditDeclarationAsync(currentSymbol, decl, editAction, cancellationToken).ConfigureAwait(false); }
/// <summary> /// Enables editing the definition of one of the symbol's declarations. /// Partial types and methods may have more than one declaration. /// </summary> /// <param name="symbol">The symbol to edit.</param> /// <param name="location">A location within one of the symbol's declarations.</param> /// <param name="editAction">The action that makes edits to the declaration.</param> /// <param name="cancellationToken">An optional <see cref="CancellationToken"/>.</param> /// <returns>The new symbol including the changes.</returns> public async Task<ISymbol> EditOneDeclarationAsync( ISymbol symbol, Location location, AsyncDeclarationEditAction editAction, CancellationToken cancellationToken = default(CancellationToken)) { var sourceTree = location.SourceTree; var doc = _currentSolution.GetDocument(sourceTree); if (doc != null) { return await this.EditOneDeclarationAsync(symbol, doc.Id, location.SourceSpan.Start, editAction, cancellationToken).ConfigureAwait(false); } doc = _originalSolution.GetDocument(sourceTree); if (doc != null) { return await this.EditOneDeclarationAsync(symbol, doc.Id, location.SourceSpan.Start, editAction, cancellationToken).ConfigureAwait(false); } throw new ArgumentException("The location specified is not part of the solution.", nameof(location)); }
private async Task<ISymbol> EditDeclarationAsync( ISymbol currentSymbol, SyntaxNode declaration, AsyncDeclarationEditAction editAction, CancellationToken cancellationToken) { var doc = _currentSolution.GetDocument(declaration.SyntaxTree); var editor = await DocumentEditor.CreateAsync(doc, cancellationToken).ConfigureAwait(false); editor.TrackNode(declaration); await editAction(editor, declaration, cancellationToken).ConfigureAwait(false); var newDoc = editor.GetChangedDocument(); _currentSolution = newDoc.Project.Solution; // try to find new symbol by looking up via original declaration var model = await newDoc.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); var newDeclaration = model.SyntaxTree.GetRoot(cancellationToken).GetCurrentNode(declaration); if (newDeclaration != null) { var newSymbol = model.GetDeclaredSymbol(newDeclaration, cancellationToken); if (newSymbol != null) { return newSymbol; } } // otherwise fallback to rebinding with original symbol return await this.GetCurrentSymbolAsync(currentSymbol, cancellationToken).ConfigureAwait(false); }
/// <summary> /// Enables editing the definition of one of the symbol's declarations. /// Partial types and methods may have more than one declaration. /// </summary> /// <param name="symbol">The symbol to edit.</param> /// <param name="editAction">The action that makes edits to the declaration.</param> /// <param name="cancellationToken">An optional <see cref="CancellationToken"/>.</param> /// <returns>The new symbol including the changes.</returns> public async Task<ISymbol> EditOneDeclarationAsync( ISymbol symbol, AsyncDeclarationEditAction editAction, CancellationToken cancellationToken = default(CancellationToken)) { var currentSymbol = await this.GetCurrentSymbolAsync(symbol, cancellationToken).ConfigureAwait(false); CheckSymbolArgument(currentSymbol, symbol); if (TryGetBestDeclarationForSingleEdit(currentSymbol, out var declaration)) { return await this.EditDeclarationAsync(currentSymbol, declaration, editAction, cancellationToken).ConfigureAwait(false); } return null; }